package com.smile.cloud.order.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.smile.cloud.order.config.SnowflakeConfig;
import com.smile.cloud.order.mapper.OrderMapper;
import com.smile.cloud.order.mapper.TransactionLogMapper;
import com.smile.cloud.order.model.Order;
import com.smile.cloud.order.model.TransactionLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQClientException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private TransactionLogMapper transactionLogMapper;
    @Resource
    private TransactionProducer transactionProducer;
    @Resource
    private SnowflakeConfig snowflakeConfig;
    @Resource
    private DelayProducer delayProducer;

    //执行本地事务时调用，将订单数据和事务日志写入本地数据库
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int createOrder(OrderDTO orderDTO, String transactionId) throws Exception {
        //订单服务 -> 创建订单 -> 库存服务 -> 扣减库存 -> 积分服务 -> 增加积分 -> 仓储服务 -> 通知发货
        //根据商品ID、商品编号检查库存存储充足才可以下单，这里省略判断，模拟库存库存不足直接返回
        int stock = (int) (Math.random() * 10);
        if (stock > 0 && orderDTO.getCount() > stock) {
            log.info("商品{},库存不足{}", orderDTO.getProductId(), orderDTO);
            return 0;
        }
        //1.创建订单
        log.info("开始创建订单订...{}", orderDTO);
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);
        order.setOrderStatus(0);
        order.setPayStatus(0);
        orderMapper.insert(order);
        log.info("完成订单创建....{}", order);





        //2.写入事务日志
        log.info("开始写入日志事务...");
        TransactionLog transactionLog = new TransactionLog();
        transactionLog.setId(transactionId);
        transactionLog.setBusiness("order");
        transactionLog.setForeignKey(String.valueOf(order.getId()));
        transactionLogMapper.insert(transactionLog);
        log.info("完成写入日志事务...{}", transactionLog);



        log.info("{} 开始发送订单支付延时消息...订单号：{}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"), order.getOrderNo());
        delayProducer.send(order.getOrderNo(), DelayProducer.TOPIC_ORDER_DELAY, 16);
        log.info("{} 完成发送订单支付延时消息...订单号：{}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"), order);

        return 1;
    }

    //前端调用，只用于向RocketMQ发送事务消息
    @Override
    public void createOrderSendMsg(OrderDTO order) throws MQClientException {
        order.setId(String.valueOf(snowflakeConfig.snowflakeId()));
        order.setOrderNo("CX" + snowflakeConfig.snowflakeIdStr());
        transactionProducer.send(JSON.toJSONString(order), "order");
    }
}
